package com.battle.service.service.impl;

import cn.afterturn.easypoi.excel.ExcelImportUtil;
import cn.afterturn.easypoi.excel.entity.ImportParams;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.json.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.battle.pojo.dto.role.UserRoleDto;
import com.battle.pojo.entity.*;
import com.battle.pojo.enums.OrganizationTypeEnum;
import com.battle.pojo.enums.UserShareTypeEnum;
import com.battle.pojo.enums.WarCaseStudyDetailsStatusEnum;
import com.battle.pojo.enums.resource.ResourceTypeEnum;
import com.battle.pojo.excel.OrganizationTreeListExcel;
import com.battle.pojo.excel.UserListExcel;
import com.battle.pojo.param.user.*;
import com.battle.pojo.vo.label.GetLabelVo;
import com.battle.pojo.vo.organization.GetOrganizationDownListVo;
import com.battle.pojo.vo.user.*;
import com.battle.pojo.dto.user.*;
import com.battle.service.repository.in.*;
import com.battle.service.service.in.LabelMpService;
import com.battle.service.service.in.ResourceService;
import com.battle.service.service.in.UserService;
import com.battle.service.utils.PasswordUtil;
import com.battle.service.utils.StringUtil;
import nirvana.core.context.WebContext;
import nirvana.core.domains.vo.PageResult;
import nirvana.core.exceptions.BizException;
import nirvana.core.utils.ids.IdGenerator;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;


import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 【描 述】：用户服务
 * 【环 境】：J2SE 17
 * 【详 细】：
 */
@Service
public class UserServiceImpl implements UserService {

    private final UserRepository userRepository;
    private final UserRoleMpRepository userRoleMpRepository;
    private final RoleRepository roleRepository;
    private final OrganizationRepository organizationRepository;
    private final LabelMpService labelMpService;
    private final WarCaseStudyRepository warCaseStudyRepository;
    private final WarCaseStudyUserRepository warCaseStudyUserRepository;
    private final UserCooperationRepository userCooperationRepository;
    private final ResourceService resourceService;
    private final UserOrganizationMpRepository userOrganizationMpRepository;
    private final PersonWarCaseRepository personWarCaseRepository;

    public UserServiceImpl(UserRepository userRepository, UserRoleMpRepository userRoleMpRepository, RoleRepository roleRepository, OrganizationRepository organizationRepository, LabelMpService labelMpService, WarCaseStudyRepository warCaseStudyRepository, WarCaseStudyUserRepository warCaseStudyUserRepository, UserCooperationRepository userCooperationRepository, ResourceService resourceService, UserOrganizationMpRepository userOrganizationMpRepository, PersonWarCaseRepository personWarCaseRepository) {
        this.userRepository = userRepository;
        this.userRoleMpRepository = userRoleMpRepository;
        this.roleRepository = roleRepository;
        this.organizationRepository = organizationRepository;
        this.labelMpService = labelMpService;
        this.warCaseStudyRepository = warCaseStudyRepository;
        this.warCaseStudyUserRepository = warCaseStudyUserRepository;
        this.userCooperationRepository = userCooperationRepository;
        this.resourceService = resourceService;
        this.userOrganizationMpRepository = userOrganizationMpRepository;
        this.personWarCaseRepository = personWarCaseRepository;
    }


    /**
     * 创建用户
     *
     * @param param
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void createUser(CreateUserParam param) {
        User user = new User();
        BeanUtils.copyProperties(param, user);
        Long id = IdGenerator.SNOW.generate();
        user.setId(id);
        user.setAccounts(param.getPhone());

        //TODO 检查account不能重复

        //设置密码
        String password = param.getPasswords();
        password = PasswordUtil.passwordBcryptEncode(id.toString(), password);
        user.setPasswords(password);

        userRepository.create(user);

        List<Long> roleIdList = param.getRoleIdList();
        if (roleIdList != null) {
            List<UserRoleMp> mpList = new ArrayList<>();
            roleIdList = roleIdList.stream()
                    .distinct()
                    .toList();
            for (Long roleId : roleIdList) {
                UserRoleMp mp = new UserRoleMp();
                mp.setUserId(id);
                mp.setRoleId(roleId);
                mp.setId(IdGenerator.SNOW.generate());
                mpList.add(mp);
            }
            userRoleMpRepository.saveBatch(mpList);
        }

        labelMpService.createLabelMp(param.getLabelIdList(),id);
    }

    /**
     * 修改用户
     *
     * @param param
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void editUser(EditUserParam param) {
        Long id = param.getId();
        User user = userRepository.getByIdCheck(id);
        BeanUtils.copyProperties(param, user);
        user.setAccounts(param.getPhone());

        //TODO 检查account不能重复

        //设置密码
        String password = param.getPasswords();
        password = PasswordUtil.passwordBcryptEncode(id.toString(), password);
        user.setPasswords(password);

        userRepository.edit(user);

        List<Long> roleIdList = param.getRoleIdList();
        userRoleMpRepository.clean(id);
        if (roleIdList != null) {
            List<UserRoleMp> mpList = new ArrayList<>();
            roleIdList = roleIdList.stream()
                    .distinct()
                    .toList();
            for (Long roleId : roleIdList) {
                UserRoleMp mp = new UserRoleMp();
                mp.setUserId(id);
                mp.setRoleId(roleId);
                mp.setId(IdGenerator.SNOW.generate());
                mpList.add(mp);
            }
            userRoleMpRepository.saveBatch(mpList);
        }

        labelMpService.createLabelMp(param.getLabelIdList(),id);
    }

    /**
     * 移除用户
     *
     * @param id
     */
    @Override
    public void removeUser(Long id) {
        User user = userRepository.getByIdCheck(id);
        if (user.getIsSystem()) {
            throw new BizException("系统用户不可编辑");
        }
        userRepository.removeById(id);
    }

    /**
     * 重置密码
     */
    @Override
    public void resetPassWordUser(Long id) {
        if (id == 0) {
            List<User> userList = userRepository.getBaseMapper().selectList(new LambdaQueryWrapper<>());
            for (User user : userList) {
                String password = "123456";
                password = PasswordUtil.passwordBcryptEncode(user.getId().toString(), password);
                user.setPasswords(password);
            }
            userRepository.updateBatchById(userList);
        } else {
            User user = userRepository.getByIdCheck(id);
            String password = "123456";
            password = PasswordUtil.passwordBcryptEncode(id.toString(), password);
            user.setPasswords(password);
            userRepository.updateById(user);
        }
    }

    /**
     * 启动/禁用用户
     *
     * @param id
     */
    @Override
    public void enabledUser(Long id) {
        User user = userRepository.getByIdCheck(id);
        if (user.getIsSystem()) {
            throw new BizException("系统用户不可编辑");
        }
        user.setIsDisable(!user.getIsDisable());
        userRepository.edit(user);
    }

    /**
     * 获取用户详情
     *
     * @param id
     * @return
     */
    @Override
    public GetUserVo getUser(Long id) {
        User user = userRepository.getByIdCheck(id);
        GetUserVo vo = new GetUserVo();
        BeanUtils.copyProperties(user, vo);
        List<Long> roleIds = roleRepository.getRoleListByUserId(id)
                .stream()
                .map(Role::getId)
                .toList();
        vo.setRoleIdList(roleIds);

        //获取对应得授权得资源
        List<ResourceTypeEnum> resourceTypeEnums = new ArrayList<>();
        resourceTypeEnums.add(ResourceTypeEnum.BUTTON);
        JSONArray resourceList = resourceService.getUserResourceListByUserId(id, resourceTypeEnums);

        if (CollectionUtil.isNotEmpty(resourceList)) {
            vo.setTagList(resourceList.stream()
                    .map(o -> ((JSONObject) o).getString("code"))
                    .collect(Collectors.toList()));
        }

        List<LabelMp> labelByFid = labelMpService.getLabelByFid(id);
        if (CollectionUtil.isNotEmpty(labelByFid)){
            List<Long> labelIdList = labelByFid.stream()
                    .map(LabelMp::getLabelId)
                    .toList();
            vo.setLabelIdList(labelIdList);
        }

        //根据浙政钉code获取人员战力
        if (user.getEmployeeCode()!=null){
            PersonWarCase personWarCase = new PersonWarCase();
            personWarCase.setIsDelete(false);
            personWarCase.setEmployeeCode(user.getEmployeeCode());
            List<PersonWarCase> listByEntity = personWarCaseRepository.getListByEntity(personWarCase);
            if (CollectionUtil.isNotEmpty(listByEntity)){
                PersonWarCase person =listByEntity.get(0);
                vo.setPersonId(person.getId());
            }
        }
        return vo;
    }

    /**
     * 获取用户 列表
     *
     * @param param
     * @return
     */
    @Override
    public PageResult<GetUserListVo> getUserList(GetUserListParam param) {

        SelectUserDto dto = new SelectUserDto();
        BeanUtils.copyProperties(param, dto);

        if (dto.getOrganizationId() != null) {
            dto.setOrganizationIdList(
                    organizationRepository.getOrganizationIdList(dto.getOrganizationId())
            );
        }

        Page<GetUserListVo> page = userRepository.selectUser(dto);

        List<GetUserListVo> userList = page.getRecords();
        if (CollectionUtil.isNotEmpty(userList)){

            List<Long> ids = userList.stream().map(GetUserListVo::getId).toList();

            Map<Long, List<GetLabelVo>> labelMp = labelMpService.getListByFidIds(ids);

            List<Long> userIds = userList.stream().map(GetUserListVo::getId).toList();
            Map<Long, List<UserRoleDto>> listMap = roleRepository.getRoleListByUserIds(userIds);

            for (GetUserListVo vo : userList) {
                vo.setEnabled(!vo.getIsDisable());
                Long id = vo.getId();
                List<UserRoleDto> roleDtoList = listMap.get(id);
                if (roleDtoList != null) {
                    String roleNames = roleDtoList.stream()
                            .map(UserRoleDto::getName)
                            .collect(Collectors.joining(","));
                    vo.setRoleName(roleNames);
                }

                List<GetLabelVo> labelVoList = labelMp.get(vo.getId());
                if (labelVoList != null) {
                    String labelName = labelVoList.stream()
                            .map(GetLabelVo::getName)
                            .collect(Collectors.joining(","));
                    vo.setLabelName(labelName);
                }

                //参加的研讨项目数量
                Integer caseNumber = getCaseNumber(vo.getId());
                vo.setCaseNumber(caseNumber);

                //贡数量=参加1个项目研讨1分，协作项目研讨结果1分
                Integer contributionNumber = getContributionNumber(vo.getId());
                vo.setContributionNumber(caseNumber+contributionNumber);
            }
        }
        return new PageResult<>(userList, page);

    }

    Integer getCaseNumber(Long userId){
        WarCaseStudyUser warCaseStudyUser = new WarCaseStudyUser();
        warCaseStudyUser.setIsDelete(false);
        warCaseStudyUser.setIsDisable(false);
        warCaseStudyUser.setUserId(userId);
        warCaseStudyUser.setStatus(WarCaseStudyDetailsStatusEnum.pass);
        List<WarCaseStudyUser> listByEntity = warCaseStudyUserRepository.getListByEntity(warCaseStudyUser);
        if (CollectionUtil.isNotEmpty(listByEntity)){
            return listByEntity.size();
        }
        return 0;
    }

    Integer getContributionNumber(Long userId){
        UserCooperation userCooperation = new UserCooperation();
        userCooperation.setIsDelete(false);
        userCooperation.setIsDisable(false);
        userCooperation.setUserId(userId);
        userCooperation.setType(UserShareTypeEnum.examplesOfBattles);
        List<UserCooperation> listByEntity = userCooperationRepository.getListByEntity(userCooperation);
        if (CollectionUtil.isNotEmpty(listByEntity)){
            return listByEntity.size();
        }
        return 0;
    }

    /**
     * 获取用户下拉列表
     *
     * @param param
     * @return
     */
    @Override
    public List<GetUserDownListVo> getUserDownList(GetUserDownListParam param) {
        User po = new User();
        if (param != null) {
            BeanUtils.copyProperties(param, po);
            po.setIsDelete(false);
        }
        List<User> userList = userRepository.getListByEntity(po);

        List<GetUserDownListVo> list = new ArrayList<>();
        for (User user : userList) {
            GetUserDownListVo vo = new GetUserDownListVo();
            BeanUtils.copyProperties(user, vo);
            list.add(vo);
        }
        return list;
    }

    /**
     * 获取当前用户的组织架构信息
     * @return
     */
    @Override
    public List<GetOrganizationDownListVo> getOrganizationByCurrentUserId() {
        List<UserOrganizationMp> userOrganizationMps = userOrganizationMpRepository.getBaseMapper().selectList(new LambdaQueryWrapper<UserOrganizationMp>()
                .eq(UserOrganizationMp::getUserId, WebContext.getCurrentUserId())
                .eq(UserOrganizationMp::getIsDelete, false));
        if (CollectionUtil.isNotEmpty(userOrganizationMps)){
            List<Long> organizationIds = userOrganizationMps.stream()
                    .map(UserOrganizationMp::getOrganizationId)
                    .toList();
            List<Organization> organizationList = organizationRepository.getBaseMapper().selectList(new LambdaQueryWrapper<Organization>()
                    .in(Organization::getId, organizationIds)
                    .eq(Organization::getIsDelete, false));
            if (CollectionUtil.isNotEmpty(organizationList)){
                List<GetOrganizationDownListVo> list = new ArrayList<>();
                for (Organization organization : organizationList) {
                    GetOrganizationDownListVo vo = new GetOrganizationDownListVo();
                    BeanUtils.copyProperties(organization, vo);
                    list.add(vo);
                }
                return list;
            }
        }

        return null;
    }


    /**
     * 导入用户
     * @param file
     */
    @Override
    @Transactional(rollbackFor = Exception.class, isolation = Isolation.READ_UNCOMMITTED)
    public void importUser(MultipartFile file) {
//        StringBuffer error = new StringBuffer();
//
//        List<User> userList=new ArrayList<>();
//        List<UserRoleMp> userRoleMpList=new ArrayList<>();
//
//        try {
//            ImportParams params = new ImportParams();
//            params.setTitleRows(0);
//            params.setStartRows(0);
//
//            List<UserListExcel> result = ExcelImportUtil.importExcel(file.getInputStream(), UserListExcel.class, params);
//            for (UserListExcel excel : result) {
//                User user = new User();
//                BeanUtils.copyProperties(excel, user);
//                user.setId(IdGenerator.SNOW.generate());
//                user.setOrganizationId(1833401111164018688L);
//                user.setPath("1833401111164018688");
//                user.setFunctionName(excel.getFunctionName());
//                user.setIsSystem(false);
//                userList.add(user);
//
//                UserRoleMp userRoleMp=new UserRoleMp();
//                userRoleMp.setUserId(user.getId());
//                userRoleMp.setRoleId(1833413907499991040L);
//                userRoleMp.setId(IdGenerator.SNOW.generate());
//                userRoleMpList.add(userRoleMp);
//            }
//
//            if (CollectionUtil.isNotEmpty(userList)){
//                userRepository.saveBatch(userList);
//            }
//            if (CollectionUtil.isNotEmpty(userRoleMpList)){
//                userRoleMpRepository.saveBatch(userRoleMpList);
//            }
//
//        }catch (Exception e){
//            e.printStackTrace();
//        }
//
//        if (!StringUtils.isEmpty(error.toString())) {
//            throw new BizException(error.toString());
//        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updatePassword(UpdatePasswordParam param) {
        Long id = param.getId();
        User user = userRepository.getByIdCheck(id);

        //校验原密码是否和输入的原密码一致
        String oldPassword = param.getPassword();
        Boolean loginSuccess = PasswordUtil.passwordConfirm(StringUtil.jointString(id.toString(), oldPassword), user.getPasswords());
        if (!loginSuccess) {
            throw new BizException("原密码错误");
        }

        String password = param.getNewPassword();
        password = PasswordUtil.passwordBcryptEncode(id.toString(), password);
        user.setPasswords(password);
        userRepository.edit(user);
    }


}



